package hn.sigit.view.workflow.transaction;

import hn.sigit.dao.hnd.ladmshadow.PropertyDAO;
import hn.sigit.dao.hnd.ladmshadow.RRRDAO;
import hn.sigit.dao.hnd.administrative.HND_NaturalPersonDAO;

import hn.sigit.model.hnd.administrative.HND_NaturalPerson;
import hn.sigit.model.hnd.ladmshadow.Property;
import hn.sigit.model.hnd.ladmshadow.RRR;
import hn.sigit.model.hnd.ladmshadow.Responsibility;
import hn.sigit.model.hnd.ladmshadow.Restriction;
import hn.sigit.model.hnd.ladmshadow.Right;
import hn.sigit.model.ladm.administrative.LA_RightType;
import hn.sigit.model.ladm.administrative.LA_RestrictionType;
import hn.sigit.model.ladm.administrative.LA_ResponsibilityType;
import hn.sigit.model.ladm.external.ExtParty;
import hn.sigit.view.ShareValue;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;

import org.richfaces.model.DataProvider;
import org.richfaces.model.ExtendedTableDataModel;
import org.richfaces.model.selection.SimpleSelection;

public class DataEntryRRRHelper implements Serializable {
	private static final long serialVersionUID = 1L;

	private DataEntryHelper dataEntryHelper;
	
	private Property property;
	private Set<RRR> rrrSet;
	
	private List<ParcelRRR> rrrsToDelete;
	
	private List<ParcelRight> parcelRightsList;
	private List<ParcelRight> newParcelRightsList;
	private ParcelRight selectedRight;
	private SelectItem[] rightTypes;
	
	private List<ParcelRestriction> parcelRestrictionsList;
	private List<ParcelRestriction> newParcelRestrictionsList;
	private ParcelRestriction selectedRestriction;
	private SelectItem[] restrictionTypes;
	
	private List<ParcelResponsibility> parcelResponsibilitiesList;
	private List<ParcelResponsibility> newParcelResponsibilitiesList;
	private ParcelResponsibility selectedResponsibility;
	private SelectItem[] responsibilityTypes;

	private ExtParty selectedNaturalPerson;
	private SimpleSelection naturalPersonPartySelection;
	private ExtendedTableDataModel<HND_NaturalPerson> dataModel;
	private List<HND_NaturalPerson> naturalPersonParties;
	private List<HND_NaturalPerson> selectedNaturalPersonParties = new ArrayList<HND_NaturalPerson>();
	private Object tableState;


	private boolean editingRights;
	private boolean editingRestrictions;
	private boolean editingResponsibilities;
	
	public DataEntryRRRHelper(DataEntryHelper dataEntryHelper) {
		this.dataEntryHelper = dataEntryHelper;
	}

	public Property getProperty() {
		if (property == null)
			property = PropertyDAO.loadPropertyById(dataEntryHelper.getSelectedBaUnitId());

		return property;
	}
	public void setProperty(Property property) {
		this.property = property;
	}

	public Set<RRR> getRrrSet() {
		if (rrrSet == null) {
			if (getProperty() != null)
				rrrSet = getProperty().getRrr();
		}
		return rrrSet;
	}
	public void setRrrSet(Set<RRR> rrrSet) {
		this.rrrSet = rrrSet;
	}

	public List<ParcelRRR> getRrrsToDelete() {
		if (rrrsToDelete == null)
			rrrsToDelete = new ArrayList<ParcelRRR>();
		return rrrsToDelete;
	}
	
	public List<ParcelRight> getParcelRightsList() {
		if (parcelRightsList == null) {
			parcelRightsList = new ArrayList<ParcelRight>();
			
			if (getRrrSet() != null) {
				ParcelRight pr;
				for (RRR rrr : getRrrSet()) {
					pr = null;
					if (rrr instanceof Right) {
						Right right = (Right)rrr;
						ExtParty extParty = right.getParty().getExtParty();
						pr = new ParcelRight(dataEntryHelper.getPresentationId(), extParty, new ShareValue(right.getShare()), right);
					}
					
					if (pr != null)
						parcelRightsList.add(pr);
				}
			}
		}
		
		return parcelRightsList;
	}
	public void setParcelRightsList(List<ParcelRight> parcelRightsList) {
		this.parcelRightsList = parcelRightsList;
	}

	public List<ParcelRight> getNewParcelRightsList() {
		if (newParcelRightsList == null) {
			newParcelRightsList = new ArrayList<ParcelRight>();
		}

		return newParcelRightsList;
	}
	public void setNewParcelRightsList(List<ParcelRight> newParcelRightsList) {
		this.newParcelRightsList = newParcelRightsList;
	}
	
	public void setSelectedRight(ParcelRight selectedRight) {
		this.selectedRight = selectedRight;
	}
	public ParcelRight getSelectedRight() {
		return selectedRight;
	}

	
	public String modifySelectedRights() {
		DataEntryRRRHelperLogic.modifySelected(parcelRightsList, newParcelRightsList);
		return null;
	}
	
	public String cancelRightsModification() {
		DataEntryRRRHelperLogic.cancelRRRsModification(newParcelRightsList);
		return null;
	}

	public String acceptRightsModification() {
		DataEntryRRRHelperLogic.acceptRRRsModification(parcelRightsList, newParcelRightsList);
		return null;
	}
	
	public String cancelRightChanges() {
		RRRDAO.clear();

		editingRights = false;
		parcelRightsList = null;
		parcelRightsList = null;
		rrrSet = null;
		property = null;
		
		return null;
	}

	public String applyRightChanges() {
		DataEntryRRRHelperLogic.applyRRRChanges(getProperty(), getRrrSet(), getParcelRightsList(), getRrrsToDelete());

		editingRights = false;
		parcelRightsList = null;
		newParcelRightsList = null;
		
		return null;
	}

	public String deleteSelectedRights() {
		DataEntryRRRHelperLogic.deleteSelectedRRRs(parcelRightsList, getRrrsToDelete());
		return null;
	}
	
	public void addNewRight() {
		if (null == newParcelRightsList || null == getSelectedNaturalPerson()) return;
		
		selectedRight = new ParcelRight(dataEntryHelper.getPresentationId(), getSelectedNaturalPerson());
		selectedRight.setNewRRR(true);
		
		newParcelRightsList.add(selectedRight);
	}

	public ShareValue getRightsSumShares() {
		return DataEntryRRRHelperLogic.getSumShares(parcelRightsList);
	}
	
	public ShareValue getRightsSumNewShares() {
		return DataEntryRRRHelperLogic.getSumShares(newParcelRightsList);
	}
	
	public SelectItem[] getRightTypes() {
		if (rightTypes == null) {
			LA_RightType[] rightTypeValues = LA_RightType.values();
			rightTypes = new SelectItem[rightTypeValues.length];
			for (int i = 0; i < rightTypeValues.length; i++) {
				LA_RightType rt = rightTypeValues[i];
				rightTypes[i] = new SelectItem(rt, dataEntryHelper.getResBundle().loadMessage(rt.toString()));
			}
		}

		return rightTypes;
	}

	
	
	/******
	 * BEGIN Properties for RESTRICTIONS
	 ****/
	public List<ParcelRestriction> getParcelRestrictionsList() {
		if (parcelRestrictionsList == null) {
			parcelRestrictionsList = new ArrayList<ParcelRestriction>();
			
			if (getRrrSet() != null) {
				ParcelRestriction pr;
				for (RRR rrr : getRrrSet()) {
					pr = null;
					if (rrr instanceof Restriction) {
						Restriction restriction = (Restriction)rrr;
						ExtParty extParty = restriction.getParty().getExtParty();
						//long presentationId, ExtParty extParty, ShareValue share, Restriction restriction
						pr = new ParcelRestriction(dataEntryHelper.getPresentationId(), extParty, new ShareValue(restriction.getShare()), restriction);
					}
					
					if (pr != null)
						parcelRestrictionsList.add(pr);
				}
			}
		}

		return parcelRestrictionsList;
	}
	public void setParcelRestrictionsList(List<ParcelRestriction> parcelRestrictionsList) {
		this.parcelRestrictionsList = parcelRestrictionsList;
	}

	public List<ParcelRestriction> getNewParcelRestrictionsList() {
		if (newParcelRestrictionsList == null) {
			newParcelRestrictionsList = new ArrayList<ParcelRestriction>();
		}
		return newParcelRestrictionsList;
	}
	public void setNewParcelRestrictionsList(List<ParcelRestriction> newParcelRestrictionsList) {
		this.newParcelRestrictionsList = newParcelRestrictionsList;
	}

	public ParcelRestriction getSelectedRestriction() {
		return selectedRestriction;
	}
	public void setSelectedRestriction(ParcelRestriction selectedRestriction) {
		this.selectedRestriction = selectedRestriction;
	}
	
	public String modifySelectedRestrictions() {
		DataEntryRRRHelperLogic.modifySelected(parcelRestrictionsList, newParcelRestrictionsList);
		return null;
	}
	
	public String cancelRestrictionsModification() {
		DataEntryRRRHelperLogic.cancelRRRsModification(newParcelRestrictionsList);
		return null;
	}

	public String acceptRestrictionsModification() {
		DataEntryRRRHelperLogic.acceptRRRsModification(parcelRestrictionsList, newParcelRestrictionsList);
		return null;
	}
	
	public String cancelRestrictionChanges() {
		RRRDAO.clear();

		editingRestrictions = false;
		parcelRestrictionsList = null;
		newParcelRestrictionsList = null;
		rrrSet = null;
		property = null;
		
		return null;
	}

	public String applyRestrictionChanges() {
		DataEntryRRRHelperLogic.applyRRRChanges(getProperty(), getRrrSet(), getParcelRestrictionsList(), getRrrsToDelete());

		editingRestrictions = false;
		parcelRestrictionsList = null;
		newParcelRestrictionsList = null;
		
		return null;
	}

	public String deleteSelectedRestrictions() {
		DataEntryRRRHelperLogic.deleteSelectedRRRs(parcelRestrictionsList, getRrrsToDelete());
		return null;
	}
	
	public void addNewRestriction() {
		if (null == newParcelRestrictionsList || null == getSelectedNaturalPerson()) return;
		
		selectedRestriction = new ParcelRestriction(dataEntryHelper.getPresentationId(), getSelectedNaturalPerson());
		selectedRestriction.setNewRRR(true);
		
		newParcelRestrictionsList.add(selectedRestriction);
	}

	public ShareValue getRestrictionsSumShares() {
		return DataEntryRRRHelperLogic.getSumShares(parcelRestrictionsList);
	}
	
	public ShareValue getRestrictionsSumNewShares() {
		return DataEntryRRRHelperLogic.getSumShares(newParcelRestrictionsList);
	}

	public SelectItem[] getRestrictionTypes() {
		String text;
		if (restrictionTypes == null) {
			LA_RestrictionType[] typeValues = LA_RestrictionType.values();
			restrictionTypes = new SelectItem[typeValues.length];
			for (int i = 0; i < typeValues.length; i++) {
				LA_RestrictionType rt = typeValues[i];
				text = dataEntryHelper.getResBundle().loadMessage(rt.toString());
				restrictionTypes[i] = new SelectItem(rt, text, "");
			}
		}

		return restrictionTypes;
	}
	/******
	 * END Properties for RESTRICTIONS
	 ****/

	/******
	 * BEGIN Properties for RESPONSIBILITIES
	 ****/
	public List<ParcelResponsibility> getParcelResponsibilitiesList() {
		if (parcelResponsibilitiesList == null) {
			parcelResponsibilitiesList = new ArrayList<ParcelResponsibility>();

			if (getRrrSet() != null) {
				ParcelResponsibility pr;
				for (RRR rrr : getRrrSet()) {
					pr = null;
					if (rrr instanceof Responsibility) {
						Responsibility responsibility = (Responsibility)rrr;
						ExtParty extParty = responsibility.getParty().getExtParty();
						pr = new ParcelResponsibility(dataEntryHelper.getPresentationId(), extParty, new ShareValue(responsibility.getShare()), responsibility);
					}
					
					if (pr != null)
						parcelResponsibilitiesList.add(pr);
				}
			}
		}
		
		return parcelResponsibilitiesList;
	}
	public void setParcelResponsibilitiesList(List<ParcelResponsibility> parcelResponsibilitiesList) {
		this.parcelResponsibilitiesList = parcelResponsibilitiesList;
	}

	public List<ParcelResponsibility> getNewParcelResponsibilitiesList() {
		if (newParcelResponsibilitiesList == null) {
			newParcelResponsibilitiesList = new ArrayList<ParcelResponsibility>();
		}
		return newParcelResponsibilitiesList;
	}
	public void setNewParcelResponsibilitiesList(List<ParcelResponsibility> newParcelResponsibilitiesList) {
		this.newParcelResponsibilitiesList = newParcelResponsibilitiesList;
	}
	
	public ParcelResponsibility getSelectedResponsibility() {
		return selectedResponsibility;
	}
	public void setSelectedResponsibility(ParcelResponsibility selectedResponsibility) {
		this.selectedResponsibility = selectedResponsibility;
	}
	
	public String modifySelectedResponsibilities() {
		DataEntryRRRHelperLogic.modifySelected(parcelResponsibilitiesList, newParcelResponsibilitiesList);
		return null;
	}
	
	public String cancelResponsibilitiesModification() {
		DataEntryRRRHelperLogic.cancelRRRsModification(newParcelResponsibilitiesList);
		return null;
	}

	public String acceptResponsibilitiesModification() {
		DataEntryRRRHelperLogic.acceptRRRsModification(parcelResponsibilitiesList, newParcelResponsibilitiesList);
		return null;
	}
	
	public String cancelResponsibilityChanges() {
		RRRDAO.clear();

		editingResponsibilities = false;
		parcelResponsibilitiesList = null;
		newParcelResponsibilitiesList = null;
		rrrSet = null;
		property = null;
		
		return null;
	}

	public String applyResponsibilityChanges() {
		DataEntryRRRHelperLogic.applyRRRChanges(getProperty(), getRrrSet(), getParcelResponsibilitiesList(), getRrrsToDelete());

		editingResponsibilities = false;
		parcelResponsibilitiesList = null;
		newParcelResponsibilitiesList = null;
		
		return null;
	}

	public String deleteSelectedResponsibilities() {
		DataEntryRRRHelperLogic.deleteSelectedRRRs(parcelResponsibilitiesList, getRrrsToDelete());
		return null;
	}
	
	public void addNewResponsibility() {
		if (null == newParcelResponsibilitiesList || null == getSelectedNaturalPerson()) return;
		
		selectedResponsibility = new ParcelResponsibility(dataEntryHelper.getPresentationId(), getSelectedNaturalPerson());
		selectedResponsibility.setNewRRR(true);
		
		newParcelResponsibilitiesList.add(selectedResponsibility);
	}

	public ShareValue getResponsibilitiesSumShares() {
		return DataEntryRRRHelperLogic.getSumShares(parcelResponsibilitiesList);
	}
	
	public ShareValue getResponsibilitiesSumNewShares() {
		return DataEntryRRRHelperLogic.getSumShares(newParcelResponsibilitiesList);
	}


	public SelectItem[] getResponsibilityTypes() {
		if (responsibilityTypes == null) {
			LA_ResponsibilityType[] typeValues = LA_ResponsibilityType.values();
			responsibilityTypes = new SelectItem[typeValues.length];
			for (int i = 0; i < typeValues.length; i++) {
				LA_ResponsibilityType rt = typeValues[i];
				responsibilityTypes[i] = new SelectItem(rt, dataEntryHelper.getResBundle().loadMessage(rt.toString()));
			}
		}

		return responsibilityTypes;
	}
	/******
	 * END Properties for RESPONSIBILITIES
	 ****/


	public List<HND_NaturalPerson> getNaturalPersonParties() {
		if (naturalPersonParties == null) {
			naturalPersonParties = HND_NaturalPersonDAO.loadNaturalPersonParties();
		}
		return naturalPersonParties;
	}
	
	public ExtParty getSelectedNaturalPerson() {
		return selectedNaturalPerson;
	}
	public void setSelectedNaturalPerson(ExtParty party) {
		selectedNaturalPerson = party;
	}
	
	public SimpleSelection getNaturalPersonPartySelection() {
		return naturalPersonPartySelection;
	}
	public void setNaturalPersonPartySelection(SimpleSelection selection) {
		naturalPersonPartySelection = selection;
	}
	
	public void takeSelection(ActionEvent ae) {
		getSelectedNaturalPersonParties().clear();
		Iterator<Object> iterator = getNaturalPersonPartySelection().getKeys();
		while (iterator.hasNext()){
			Object key = iterator.next();
			selectedNaturalPerson = getNaturalPersonPartiesDataModel().getObjectByKey(key);
			//getSelectedNaturalPersonParties().add(getNaturalPersonPartiesDataModel().getObjectByKey(key));
		}
	}
	
	public List<HND_NaturalPerson> getSelectedNaturalPersonParties() {
		return selectedNaturalPersonParties;
	}
	public void setSelectedNaturalPersonParties(
			List<HND_NaturalPerson> selectedNaturalPersonParties) {
		this.selectedNaturalPersonParties = selectedNaturalPersonParties;
	}
	
	public Object getTableState() {
		return tableState;
	}
	public void setTableState(Object tableState) {
		this.tableState = tableState;
	}
	
	public boolean isEditingRights() {
		return editingRights;
	}
	public void setEditingRights(boolean editingRights) {
		this.editingRights = editingRights;
	}

	public boolean isEditingRestrictions() {
		return editingRestrictions;
	}
	public void setEditingRestrictions(boolean editingRestrictions) {
		this.editingRestrictions = editingRestrictions;
	}

	public boolean isEditingResponsibilities() {
		return editingResponsibilities;
	}
	public void setEditingResponsibilities(boolean editingResponsibilities) {
		this.editingResponsibilities = editingResponsibilities;
	}

	public ExtendedTableDataModel<HND_NaturalPerson> getNaturalPersonPartiesDataModel() {
		if (dataModel == null) {
			dataModel = new ExtendedTableDataModel<HND_NaturalPerson>(new DataProvider<HND_NaturalPerson>() {
 
				private static final long serialVersionUID = 5054087821033164847L;

				public int getRowCount() {
					return getNaturalPersonParties().size();
				}
				public List<HND_NaturalPerson> getItemsByRange(int firstRow, int endRow) {
					return getNaturalPersonParties().subList(firstRow, endRow);
				}

				public HND_NaturalPerson getItemByKey(Object key) {
					//TODO: Eliminar busqueda lineal
					for (HND_NaturalPerson npp : getNaturalPersonParties())
						if (key.equals(getKey(npp)))
							return npp;

					return null;
				}
 
 				public Object getKey(HND_NaturalPerson item) {
					return item.getExtPID();
				}
			});
 		}
		return dataModel;
 	}

	public boolean isEditing() {
		return editingRights || editingRestrictions || editingResponsibilities;
	}
}
